/**
 * 
 */
package com.xb.cloud.product.merchant.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xb.cloud.common.client.bo.PageBo;
import com.xb.cloud.common.constant.DbConstants;
import com.xb.cloud.common.model.tree.TreeNode;
import com.xb.cloud.common.model.tree.TreeUtils;
import com.xb.cloud.common.util.BeanUtils;
import com.xb.cloud.product.merchant.service.client.ShopNavigationGroupService;
import com.xb.cloud.product.merchant.service.client.bo.EndMerchantUserBo;
import com.xb.cloud.product.merchant.service.client.bo.ProductSkuBo;
import com.xb.cloud.product.merchant.service.client.bo.ShopNavSkuRequestBo;
import com.xb.cloud.product.merchant.service.client.bo.ShopNavigationGroupBo;
import com.xb.cloud.product.merchant.service.client.input.bo.ShopNavigationGroupInput;
import com.xb.cloud.product.service.business.model.GroupCount;
import com.xb.cloud.product.service.business.model.ShopGroupSku;
import com.xb.cloud.product.service.business.model.ShopGroupSkuExample;
import com.xb.cloud.product.service.business.model.ShopNavigationGroup;
import com.xb.cloud.product.service.business.model.ShopNavigationGroupExample;
import com.xb.cloud.product.service.business.model.ShopNavigationGroupExample.Criteria;
import com.xb.cloud.product.service.business.model.mapper.ShopGroupSkuMapper;
import com.xb.cloud.product.service.business.model.mapper.ShopNavigationGroupMapper;
import com.xb.cloud.product.service.client.SkuService;
import com.xb.cloud.service.client.ServiceReturnCodes;
import com.xb.cloud.service.client.ServiceReturnInfo;
import com.xb.cloud.service.client.ServiceReturnUtils;

/**
 * 
 * 商店内导航分组 管理服务类;
 * 
 * @author kexue
 *
 */
@Service
public class ShopNavigationGroupServiceImpl extends AbstractService implements ShopNavigationGroupService {

	private static final Logger LOGGER = LoggerFactory.getLogger(ShopNavigationGroupServiceImpl.class);

	@Resource
	private ShopNavigationGroupMapper shopNavigationGroupMapper;

	@Resource
	private ShopGroupSkuMapper shopGroupSkuMapper;
	@Autowired
	private SkuService skuService;

	/**
	 * 创建店铺分组
	 */
	@Override
	public ServiceReturnInfo createShopNavicationGroup(ShopNavigationGroupInput groupInput,
			EndMerchantUserBo endMerchantUserBo) {
		// 一级节点，set parentId=0
		long groupParentId = groupInput.getGroupParentId() == null ? DbConstants.PARENT_ID_0
				: groupInput.getGroupParentId();

		ShopNavigationGroup group = new ShopNavigationGroup();
		group.setId(ipKeyGenerator.generateKey());
		group.setCompanyId(endMerchantUserBo.getCompanyId());
		group.setShopId(endMerchantUserBo.getShopId());
		group.setGroupCode(groupInput.getGroupCode());
		group.setGroupDesc(groupInput.getGroupDesc());
		group.setGroupIconUrl(groupInput.getGroupIconUrl());
		group.setGroupIsLeaf(groupInput.getGroupIsLeaf());
		group.setGroupName(groupInput.getGroupName());
		group.setGroupParentId(groupParentId);
		group.setGroupSort(getNextSort(endMerchantUserBo.getShopId(), groupParentId));// TODO
																						// 当前店铺下，父节点下的子节点的最大值
		group.setLayerNo(getNextLayerNo(endMerchantUserBo.getShopId()));// TODO
																		// 层编号
		group.setLayers(getNextLayer(groupParentId, group.getLayerNo()));// TODO
																			// 层级

		group.setCreateTime(timeService.getDate());
		group.setCreateUserId(endMerchantUserBo.getId());
		group.setCreateUserName(endMerchantUserBo.getLoginName());
		shopNavigationGroupMapper.insertSelective(group);
		return ServiceReturnUtils.success();
	}

	// 唯一约束 ： shopId_parentId_sort_unique
	private Integer getNextSort(Long shopId, Long groupParentId) {
		Integer maxSort = shopNavigationGroupMapper.selectMaxSort(shopId, groupParentId);
		return maxSort == null ? 1 : maxSort + 1;
	}

	// 唯一约束 ：shopId_layerno_unique
	private Integer getNextLayerNo(Long shopId) {
		Integer maxLayerNo = shopNavigationGroupMapper.selectMaxLayerNo(shopId);
		return maxLayerNo == null ? 1 : maxLayerNo + 1;
	}

	// 层级拼接
	private String getNextLayer(Long groupParentId, int layerNo) {
		if (groupParentId == DbConstants.PARENT_ID_0) {
			// 根节点对应 ：0/
			return DbConstants.PARENT_ID_0_LAYERS + layerNo + DbConstants.LAYERS_END;
		} else {
			ShopNavigationGroup parentGroup = shopNavigationGroupMapper.selectByPrimaryKey(groupParentId);
			return parentGroup.getLayers() + layerNo + DbConstants.LAYERS_END;
		}
	}

	/**
	 * 查看某个店铺分组树形数据(由小到大)
	 */
	@Override
	public ServiceReturnInfo getShopNavicationGroup(Long shopId) {

		ShopNavigationGroupExample navGroupExample = new ShopNavigationGroupExample();
		Criteria createCriteria = navGroupExample.createCriteria();
		createCriteria.andShopIdEqualTo(shopId);
		createCriteria.andIsDeletedEqualTo(DbConstants.IS_DELETED_FALSE);
		createCriteria.andIsEnabledEqualTo(DbConstants.TRUE);
		List<ShopNavigationGroup> navigationGroupList = shopNavigationGroupMapper.selectByExample(navGroupExample);

		// 获取各个分组的在售的sku的数量，
		List<GroupCount> groupCountList = shopGroupSkuMapper.countSaleSkuForGroups(shopId);

		Iterator<ShopNavigationGroup> iterable = navigationGroupList.iterator();
		while (iterable.hasNext()) {
			ShopNavigationGroup group = iterable.next();

			if (isExistSkuByGroup(group, groupCountList)) {
				// 有数据
				group.setIsHasSku(DbConstants.TRUE);
			} else {
				// 无数据
				group.setIsHasSku(DbConstants.FALSE);

			}
		}

		// 通用列表转换成树形列表
		List<TreeNode<ShopNavigationGroupBo>> treeNodeList = convertToTreeNodeList(navigationGroupList);

		// 使用工具类构建树形结构
		TreeNode<ShopNavigationGroupBo> tree = TreeUtils.buildTree(treeNodeList);
		return ServiceReturnUtils.success(tree);
	}

	/**
	 * 判断当前分组是否包含在售的sku
	 * 
	 * @param group
	 * @param groupCountList
	 * @return
	 */
	private boolean isExistSkuByGroup(ShopNavigationGroup group, List<GroupCount> groupCountList) {
		for (GroupCount groupCount : groupCountList) {
			if (group.getId().equals(groupCount.getGroupId())) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 将店铺内分组pojo列表，转换为通用树节点列表
	 * 
	 * @param navigationGroupList
	 * @return
	 */
	private List<TreeNode<ShopNavigationGroupBo>> convertToTreeNodeList(List<ShopNavigationGroup> navigationGroupList) {

		List<TreeNode<ShopNavigationGroupBo>> treeNodeList = new ArrayList<TreeNode<ShopNavigationGroupBo>>();
		for (ShopNavigationGroup group : navigationGroupList) {
			TreeNode<ShopNavigationGroupBo> treeNode = new TreeNode<ShopNavigationGroupBo>();
			treeNode.setId(group.getId());
			treeNode.setCode(group.getGroupCode());
			treeNode.setIsLeaf(group.getGroupIsLeaf());
			treeNode.setName(group.getGroupName());
			treeNode.setParentId(group.getGroupParentId());
			treeNode.setSort(group.getGroupSort());
			treeNode.setLayerNo(group.getLayerNo());
			treeNode.setLayers(group.getLayers());
			// 设置data
			treeNode.setData(BeanUtils.newAndCopyProperties(ShopNavigationGroupBo.class, group));
			treeNodeList.add(treeNode);
		}
		return treeNodeList;

	}

	@Override
	public ServiceReturnInfo deleteShopNavicationGroup(Long groupId) {
		shopNavigationGroupMapper.deleteByPrimaryKey(groupId);
		return ServiceReturnUtils.success();
	}

	@Override
	public ServiceReturnInfo updateShopNavicationGroup(String groupId, ShopNavigationGroupInput groupInput,
			EndMerchantUserBo endMerchantUserBo) {
		// 一级节点，设置父id
		long groupParentId = groupInput.getGroupParentId() == null ? DbConstants.PARENT_ID_0
				: groupInput.getGroupParentId();

		ShopNavigationGroup group = shopNavigationGroupMapper.selectByPrimaryKey(Long.parseLong(groupId));
		group.setGroupCode(groupInput.getGroupCode());
		group.setGroupDesc(groupInput.getGroupDesc());
		group.setGroupIconUrl(groupInput.getGroupIconUrl());
		group.setGroupIsLeaf(groupInput.getGroupIsLeaf()); // 是否是叶子节点
		group.setGroupName(groupInput.getGroupName());
		group.setGroupParentId(groupParentId);
		group.setGroupSort(getNextSort(endMerchantUserBo.getShopId(), groupParentId));// TODO
																						// 当前店铺下，父节点下的子节点的最大值
		group.setLayerNo(getNextLayerNo(endMerchantUserBo.getShopId()));// TODO
																		// 层编号
		group.setLayers(getNextLayer(groupParentId, group.getLayerNo()));// TODO
																			// 层级

		group.setUpdateTime(timeService.getDate());
		group.setUpdateUserId(endMerchantUserBo.getId());
		group.setUpdateUserName(endMerchantUserBo.getLoginName());
		shopNavigationGroupMapper.updateByPrimaryKeySelective(group);
		return ServiceReturnUtils.success();
	}

	/**
	 * 
	 * @param groupId
	 * @return
	 * @see com.xb.cloud.product.merchant.service.client.ShopNavigationGroupService#getShopNavicationGroup(java.lang.String)
	 */
	@Override
	public ServiceReturnInfo getShopNavicationGroup(String groupId) {
		ShopNavigationGroup shopNavigationGroup = shopNavigationGroupMapper.selectByPrimaryKey(Long.parseLong(groupId));
		if (shopNavigationGroup != null) {
			return ServiceReturnUtils.success(shopNavigationGroup);
		} else {
			return null;
		}
	}

	/**
	 * 
	 * @param id
	 * @return
	 * @see com.xb.cloud.product.merchant.service.client.ShopNavigationGroupService#getShopNavicationGroupByParentId(java.lang.Long)
	 */
	@Override
	public ServiceReturnInfo getShopNavicationGroupByParentId(Long id) {
		ShopNavigationGroupExample example = new ShopNavigationGroupExample();
		example.createCriteria().andGroupParentIdEqualTo(id);
		List<ShopNavigationGroup> list = shopNavigationGroupMapper.selectByExample(example);
		return ServiceReturnUtils.success(list);
	}

	@Override
	public ServiceReturnInfo getSkuList(ShopNavSkuRequestBo requestBo) {
		// TODO 没有做分页
		if (requestBo.getType() == 0) {
			ServiceReturnInfo rtnData = skuService.getSkuListByGroup(requestBo.getShopId(), requestBo.getGroupId(),
					requestBo.getPageNum(), 100, 0, 0);
			PageBo<ProductSkuBo> pageBo = (PageBo<ProductSkuBo>) rtnData.getData();
			List<ProductSkuBo> skuList = pageBo.getRows();
			return ServiceReturnUtils.success(skuList);
		} else {
			ShopGroupSkuExample example = new ShopGroupSkuExample();
			example.createCriteria().andGroupIdEqualTo(requestBo.getGroupId());
			List<ShopGroupSku> selectedSkuList = shopGroupSkuMapper.selectByExample(example);
			// group 为null 表示获取所有的sku列表
			ServiceReturnInfo rtnData = skuService.getSkuListByGroup(requestBo.getShopId(), null,
					requestBo.getPageNum(), 100, 0, 0);
			PageBo<ProductSkuBo> pageBo = (PageBo<ProductSkuBo>) rtnData.getData();
			List<ProductSkuBo> allSkuList = pageBo.getRows();

			List<ProductSkuBo> displaySkuList = new ArrayList<ProductSkuBo>();
			List<Long> skuIds = new ArrayList<Long>();
			for (ProductSkuBo productSkuBo : allSkuList) {
				boolean haveTheSku = false;
				for (ShopGroupSku shopGroupSku : selectedSkuList) {
					if (productSkuBo.getId().equals(shopGroupSku.getSkuId())) {
						haveTheSku = true;
						break;
					}
				}
				if (!haveTheSku) {
					displaySkuList.add(productSkuBo);
				}
			}

			return ServiceReturnUtils.success(displaySkuList);
		}

	}

	@Override
	public ServiceReturnInfo addSku(Long groupId, Long shopId, Long skuId) {
		// TODO:应该首先判断sku是否可以
		// skuService.
		ShopGroupSku groupSku = new ShopGroupSku();
		groupSku.setShopId(shopId);
		groupSku.setGroupId(groupId);
		groupSku.setSkuId(skuId);
		// groupSku.setCreateUserId(createUserId);
		groupSku.setCreateTime(this.getTimeService().getDate());
		int insertStatus = shopGroupSkuMapper.insertSelective(groupSku);
		if (insertStatus == 1) {
			return ServiceReturnUtils.success();
		} else {
			return ServiceReturnUtils.error(ServiceReturnCodes.SYSTEM_EXCEPTION);
		}
	}

	@Override
	public ServiceReturnInfo removeSku(Long groupId, Long shopId, Long skuId) {
		ShopGroupSkuExample example = new ShopGroupSkuExample();
		example.createCriteria().andShopIdEqualTo(shopId).andSkuIdEqualTo(skuId).andGroupIdEqualTo(groupId);
		int deleteCount = shopGroupSkuMapper.deleteByExample(example);
		if (deleteCount == 1) {
			return ServiceReturnUtils.success();
		} else {
			return ServiceReturnUtils.error(ServiceReturnCodes.SYSTEM_EXCEPTION);
		}
	}

	@Override
	public ServiceReturnInfo getGroupSkuCount(ShopNavSkuRequestBo requestBo) {
		ServiceReturnInfo rtnData = skuService.getGroupSkuCount(requestBo.getShopId(), requestBo.getGroupId());
		return rtnData;
	}
}
